// State 与 props类似，但是State是私有的，并且完全受控于当前组件

// 1.0 一个计时器的例子
function tick() {
  const element = (
    <div>
      <h1>Hello, World</h1>
      <h2>It is { (new Date).toLocaleString() }</h2>
    </div>
  )
  ReactDOM.render(
    element,
    document.getElementById('root')
  )
}
setInterval(() => {
  tick
}, 1000);

// 2.0 封装Clock组件
function Clock(props) {
  return (
    <div>
      <h1>Hello, World</h1>
      <h2>It is { props.date.toLocaleString() }</h2>
    </div>
  )
}
function tick() {
  ReactDOM.render(
    <Clock date={new Date()} />,
    document.getElementById('root')
  )
}
setInterval(tick, 1000)

// 3.0 实现Clock组件内部自动更新时间 UI
class Clock extends React.Component {
  constructor(props) {
    super(props);  // 执行父类方法
    this.state = { date: new Date() };  // 赋值state
  }
  componentDidMount() {  // 生命周期：渲染到页面时
    this.timerId = setInterval(() => {
      this.tick(), 1000
    })
  }
  componentWillUnmount() {  // 生命周期：组件销毁时
    clearInterval(this.timerId)
  }
  tick() {
    this.setState({  // 只能使用这种方式改变state
      date: new Date()
    });
  }
  render() {
    return (
      <div>
        <h1>Hello, World!</h1>
        <h2>It is {this.state.date.toLocaleString()}.</h2>
      </div>
    );
  }
}
ReactDOM.render(<Clock />, document.getElementById("root"));

/**
 * 不能直接修改state，必须要使用setState()方法
 * setState()方法，对state的修改可能是异步的，所以可以传入一个函数来判断state的值，从而进行下一步工作。
 * 使用setState()时，会将传入的对象合并到state上，但是是浅合并
 * state 是内部的属性，外部无法访问，但是可以将state作为 props 的值返回到组件中
*/